//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package project_dao

import (
	"context"
	"fmt"

	"atomgit.com/openlinksaas-org/api-server/dao/db_ns"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
)

const (
	COUNTER_KEY_ISSUE_ID = "issueId"
	// COUNTER_KEY_TEST_CASE_ID = "testCaseId"
)

type ProjectCounterDbItem struct {
	CounterId  string `bson:"_id"`
	ProjectId  string `bson:"projectId"`
	CounterKey string `bson:"counterKey"`
	Value      uint64 `bson:"value"`
}

type _ProjectCounterDao struct {
	mc *mongo.Collection
}

func newProjectCounterDao(db *mongo.Database) (*_ProjectCounterDao, error) {
	mc := db.Collection(db_ns.DB_NS_PROJECT + "counter")
	_, err := mc.Indexes().CreateOne(context.Background(), mongo.IndexModel{
		Keys: bson.M{"projectId": 1},
	})
	if nil != err {
		return nil, err
	}
	return &_ProjectCounterDao{mc: mc}, nil
}

func (db *_ProjectCounterDao) Exist(ctx context.Context, projectId, counterKey string) (bool, error) {
	counterId := db.genCounterId(projectId, counterKey)
	count, err := db.mc.CountDocuments(ctx, bson.M{"_id": counterId, "projectId": projectId})
	return count > 0, err
}

func (db *_ProjectCounterDao) Insert(ctx context.Context, projectId, counterKey string) error {
	counterId := db.genCounterId(projectId, counterKey)
	_, err := db.mc.InsertOne(ctx, &ProjectCounterDbItem{
		CounterId:  counterId,
		ProjectId:  projectId,
		CounterKey: counterKey,
		Value:      0,
	})
	return err
}

func (db *_ProjectCounterDao) GetNextValue(ctx context.Context, projectId, counterKey string) (uint64, error) {
	counterId := db.genCounterId(projectId, counterKey)
	dbItem := &ProjectCounterDbItem{}
	err := db.mc.FindOneAndUpdate(ctx, bson.M{"_id": counterId}, bson.M{"$inc": bson.M{"value": 1}}).Decode(dbItem)
	if err != nil {
		return 0, err
	}
	return dbItem.Value + 1, nil
}

func (db *_ProjectCounterDao) genCounterId(projectId, counterKey string) string {
	return fmt.Sprintf("%s:%s", projectId, counterKey)
}
